<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>
<script>
    // 在ES5中，只能对数组对象进行迭代，而underscore提供的迭代方法，除了支持array，
    // 还支持object的迭代，对object迭代的依据是对象的键序列keys，我们可以查看underscore中的_.each方法：
    _.each = _.forEach = function(obj, iteratee, context) {
        // 首先要优化回调过程
        iteratee = optimizeCb(iteratee, context);
        var i, length;
        // 区分数组和对象的迭代过程
        if (isArrayLike(obj)) {
            for (i = 0, length = obj.length; i < length; i++) {
                // 数组的迭代回调传入三个参数(迭代值, 迭代索引, 迭代对象)
                iteratee(obj[i], i, obj);
            }
        } else {
            var keys = _.keys(obj);
            for (i = 0, length = keys.length; i < length; i++) {
                // 对象的迭代回调传入三个参数(迭代值, 迭代的key, 迭代对象)
                iteratee(obj[keys[i]], keys[i], obj);
            }
        }
        // 返回对象自身, 以便进行链式构造
        return obj;
    };

    // 可以看到，array是直接迭代数组的每个元素，而 object 迭代的元素是对象的每个k-v对。看一下用例：
    var obj = {
        name: 'wxj',
        age: 13,
        sex: 'male'
    };
    _.each(obj, function(value, key, obj) {
        console.log('[' + key + '] is:', value);
    });
    // name's value is: wxj
    // ...
    // ...
</script>

</html>